package com.wstuo.common.config.category.service;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.config.category.dao.IEventCategoryDAO;
import com.wstuo.common.config.category.dto.CategoryTreeViewDTO;
import com.wstuo.common.config.category.dto.EventCategoryDTO;
import com.wstuo.common.config.category.dto.PullDownTreeViewDTO;
import com.wstuo.common.config.category.entity.EventCategory;
import com.wstuo.common.config.dictionary.dao.IDataDictionaryGroupDAO;
import com.wstuo.common.config.dictionary.entity.DataDictionaryGroup;
import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.exception.ApplicationException;
import com.wstuo.common.file.csv.CSVReader;
import com.wstuo.common.file.csv.CSVWriter;
import com.wstuo.common.security.dao.IFunctionDAO;
import com.wstuo.common.security.dao.IOperationDAO;
import com.wstuo.common.security.dao.IRoleDAO;
import com.wstuo.common.security.dto.OperationDTO;
import com.wstuo.common.security.entity.Function;
import com.wstuo.common.security.entity.Operation;
import com.wstuo.common.security.entity.Resource;
import com.wstuo.common.security.entity.Role;
import com.wstuo.common.security.service.IOperationService;
import com.wstuo.common.security.service.IRoleService;
import com.wstuo.common.security.service.IUserInfoService;
import com.wstuo.common.security.utils.AppContext;
import com.wstuo.common.security.utils.FileEncodeUtils;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.StringUtils;

/**
 * Event category business logic Class
 * 
 * @version 0.1
 * @author Jet
 *  date 2010-9-10
 */
public class EventCategoryService implements IEventCategoryService {
	final static Logger LOGGER = Logger.getLogger(EventCategoryService.class);
	@Autowired
	private IEventCategoryDAO eventCategoryDAO;
	@Autowired
	private IOperationDAO operationDAO;
	@Autowired
	private IFunctionDAO functionDAO;
	@Autowired
	private IOperationService operationService;
	@Autowired
	private IUserInfoService userInfoService;
	@Autowired
	private IRoleDAO roleDAO;
	@Autowired
	private AppContext appctx;
	public static final Byte NORMAL = 0;
	@Autowired
	private IDataDictionaryGroupDAO dataDictionaryGroupDAO;


    /**
     * 判断分类是否存在
     * @param ec
     */
	@Transactional
	public boolean isCategoryExisted(EventCategoryDTO ec) {
		if(ec!=null && ec.getEventId()!=null){
			EventCategory eventCategory = eventCategoryDAO.findById(ec.getEventId());
			if (ec.getParentEventId() == null && eventCategory!=null && eventCategory.getParentEvent()!=null) {
				 ec.setParentEventId(eventCategory.getParentEvent().getEventId());
		    }
		    if (ec.getEventName() == null && eventCategory!=null) {
		    	 ec.setEventName(eventCategory.getEventName());
		    }
		}
		boolean bool = eventCategoryDAO.isCategoryExisted(ec);
	    return bool;
	}
	
	   /**
     * 判断编辑时分类是否存在
     * @param dto
     * @return
     */
	@Transactional
    public boolean isCategoryExistdOnEdit(EventCategoryDTO dto) {
        boolean flag = true;
        EventCategory category = eventCategoryDAO.findById(dto.getEventId());
        if (category!=null && dto.getEventName()!=null && dto.getEventName().equals(category.getEventName())) {
            flag = false;
        } else {
            flag = this.isCategoryExisted(dto);
        }
        return flag;
    }
	
	/**
	 * Save node
	 * 
	 * @param ecDTO
	 */
	@Transactional
	public EventCategory saveEventCategory(EventCategoryDTO ecDTO) {
		// Entity object
		EventCategory ecEtity = new EventCategory();
		EventCategoryDTO.dto2entity(ecDTO, ecEtity);
		
		if (ecDTO.getParentEventId() != null) {
			EventCategory parentTree = eventCategoryDAO.findById(ecDTO.getParentEventId());
			ecEtity.setParentEvent(parentTree);
		}
        eventCategoryDAO.save(ecEtity);
        if(ecEtity.getParentEvent()!=null){
            ecEtity.setPath(ecEtity.getParentEvent().getPath()+ecEtity.getEventId()+"/");
        }else{
            ecEtity.setPath(ecEtity.getEventId()+"/");
        }
        addCategoryOperation(ecEtity);
        ecDTO.setEventId(ecEtity.getEventId());
        return ecEtity;
	}

	/**
	 * 添加
	 * @param  cat 属于什么分类
	 */
	@Transactional
	private void addCategoryFunction(String cat) {
		LanguageContent languageContent = LanguageContent.getInstance();
		if("Knowledge".equals(cat)){
			// VAN 2011-08-05
			Function function = functionDAO.findUniqueBy("resCode","Knowledge_Category_View");// 功能不存在则添加一个
			if (function == null) {
				function = new Function();
				// 父节点
				function.setParentFunction(functionDAO.findUniqueBy("resCode",
						"KNOWLEDGEBASE_MAIN"));
				function.setResName(languageContent
						.getContent("knowledge.knowledgeCategory"));
				function.setResCode("Knowledge_Category_View");
				function.setResUrl("Knowledge_Category_View");
				functionDAO.save(function);
			}
		}else if("Request".equals(cat)){
			Function functionRequest = functionDAO.findUniqueBy("resCode",
					"Request_Category_View");// 功能不存在则添加一个
			if (functionRequest == null) {
				functionRequest = new Function();
				// 父节点
				functionRequest.setParentFunction(functionDAO.findUniqueBy(
						"resCode", "REQUEST_MAIN"));
				functionRequest.setResName(languageContent
						.getContent("setting.requestCategory"));
				functionRequest.setResCode("Request_Category_View");
				functionRequest.setResUrl("Request_Category_View");
				functionDAO.save(functionRequest);
			}
		}
	}

	/**
	 * 添加分类对应的资源.
	 * 
	 * @param entity
	 */
	@Transactional
	private void addCategoryOperation(EventCategory entity) {
		EventCategory parentEvent = entity.getParentEvent();
		String resName = entity.getEventName()+ "("+ entity.getEventId() + ")";
		if(parentEvent!=null){
			resName = parentEvent.getEventName()+"/"+resName;
		}
		String cat = getCategoryChar(entity);// 是什么分类
		if (cat != "") {
			addCategoryFunction(cat);
			Operation operations = operationDAO.findUniqueBy("resCode",cat+"_Category_"+entity.getEventId());
			Byte dataFlags=99;
			if(operations!=null&&operations.getDataFlag().equals(dataFlags)){//如果存在权限资源则原地复活
				Byte dataFlag = 0;
				operations.setDataFlag(dataFlag);
				operations.setResName(resName);
				operations.setResCode(cat + "_Category_" + entity.getEventId());
				operations.setResUrl(cat + "_Category_" + entity.getEventId());
				Function function = functionDAO.findUniqueBy("resCode", cat+"_Category_View");
				operations.setFunction(function);
				operationDAO.merge(operations);
			}else{//不存在则继续添加资源
				OperationDTO operationDTO = new OperationDTO();
				operationDTO.setResName(resName);
				operationDTO.setResCode(cat + "_Category_" + entity.getEventId());
				operationDTO.setResUrl(cat + "_Category_" + entity.getEventId());
				operationDTO.setFunctionResCode(cat + "_Category_View");
				operationService.addOperation(operationDTO);
			}
			// 将请求分类的父节点权限赋给所有角色
			if (cat.equals(entity.getCategoryRoot())) {
				String resouceCode = cat +"_Category_" + entity.getEventId();
				List<Role> roles = roleDAO.findAll();
				Operation operation = operationDAO.findUniqueBy("resCode",resouceCode);
				for (Role role : roles) {
					if (role != null) {
						if(role.getResources()!=null){
							role.getResources().add(operation);
						}else{
							Set<Resource> resources = new HashSet<Resource>();
							resources.add(operation);
							role.setResources(resources);
						}
						roleDAO.merge(role);
					}
				}
			} else {
				Role role = roleDAO.findUniqueBy("roleCode", IRoleService.ROLE_SYSADMIN);
				if (role != null) {
					Operation operation = operationDAO.findUniqueBy("resCode",cat+"_Category_"+entity.getEventId());
					if(role.getResources()!=null){
						role.getResources().add(operation);
					}else{
						Set<Resource> resources = new HashSet<Resource>();
						resources.add(operation);
						role.setResources(resources);
					}
					roleDAO.merge(role);
				}
			}
		}
	}

	/**
	 * 修改分类对应的资源。
	 * 
	 * @param entity
	 */
	@Transactional
	private void editCategoryOperation(EventCategory entity) {
		EventCategory parentEvent = entity.getParentEvent();
		String resName = entity.getEventName()+ "("+ entity.getEventId() + ")";
		if(parentEvent!=null){
			resName = parentEvent.getEventName()+"/"+resName;
		}
		String cat = getCategoryChar(entity);// 是什么分类
		if (!"".equals(cat)) {
			addCategoryFunction(cat);
			Operation operation = operationDAO.findUniqueBy("resCode", cat
					+ "_Category_" + entity.getEventId());
			if (operation != null) {

				OperationDTO operationDTO = new OperationDTO();
				OperationDTO.entity2dto(operation, operationDTO);
				operationDTO.setResName(resName);
				operationDTO.setResCode(cat + "_Category_"
						+ entity.getEventId());
				operationDTO
						.setResUrl(cat + "_Category_" + entity.getEventId());
				operationDTO.setFunctionResCode(cat + "_Category_View");
				operationService.upadteOperation(operationDTO);
			}

		}

	}

	/**
	 * 删除对应的资源.
	 * 
	 * @param eventId
	 */
	@Transactional
	private void deleteCateGoryOperation(Long eventId) {

		// Van 2011-08-05
		Operation operation = operationDAO.findUniqueBy("resCode",
				"Knowledge_Category_" + eventId);
		if (operation != null) {// 删除相应资源
			Byte del = 99;
			operation.setDataFlag(del);
			operationDAO.merge(operation);
			// operationService.deleteOperation(operation.getResNo());
		} else {
			Operation operationRequest = operationDAO.findUniqueBy("resCode",
					"Request_Category_" + eventId);
			if (operationRequest != null) {// 删除相应资源
				Byte del = 99;
				operationRequest.setDataFlag(del);
				operationDAO.merge(operationRequest);
			}
		}
		
	}

	/**
	 * 根据EventCategory实体得到对应的分类字符串
	 * @param ec
	 * @return String <br>返回的对应的分类字符串，如："Knowledge" or "Request" or ""
	 */
	private String getCategoryChar(EventCategory ec) {
		String result = "";
		String ecPath = ec.getPath().replaceAll("null","");
		long categoryParentId =Long.parseLong((ecPath.split("/")[0]));
		EventCategory rootCategory = eventCategoryDAO.findById(categoryParentId);
		if(rootCategory!=null){
			if(("Knowledge").equals(rootCategory.getCategoryRoot())){
				result = "Knowledge";
			}else if(("Request").equals(rootCategory.getCategoryRoot())){
				result = "Request";
			}
		}
		return result;

	}

	/**
	 * 同步操作.
	 * 
	 * @param ec
	 */
	private void syncKnowledgeCategoryOperation(EventCategory ec) {
		String cat = getCategoryChar(ec);// 是什么分类
		if (!"".equals(cat)) {
			Operation operation = operationDAO.findUniqueBy("resCode", cat
					+ "_Category_" + ec.getEventId());

			if (operation == null) {
				addCategoryOperation(ec);
			}
		}

	}

	/**
	 * 同步知识库分类和资源.
	 */
	@Transactional
	public void syncKnowledgeCategorys() {
		List<EventCategory> knowledgeParents = eventCategoryDAO
				.findTreeViews("Knowledge");
		List<EventCategory> allKnowledges = new ArrayList<EventCategory>();
		// 递归，获取所有知识分类
		if (knowledgeParents != null && knowledgeParents.size() > 0) {
			for (EventCategory ec : knowledgeParents) {
				cycleSubCategory(ec, allKnowledges);
			}
		}
		// 循环，同步所有分类到资源
		if (allKnowledges != null && allKnowledges.size() > 0) {
			for (EventCategory ec : allKnowledges) {
				Operation operation = operationDAO.findUniqueBy("resCode",
						"Knowledge_Category_" + ec.getEventId());
				if (operation == null) {
					addCategoryOperation(ec);
				}// 同步资源
			}
		}

	}

	/**
	 * 同步请求分类到资源.
	 */
	@Transactional
	public void syncRequestCategorys() {

		List<EventCategory> requestParents = eventCategoryDAO
				.findTreeViews("Request");
		List<EventCategory> allRequests = new ArrayList<EventCategory>();
		// 递归，获取所有知识分类
		if (requestParents != null && requestParents.size() > 0) {
			for (EventCategory ec : requestParents) {
				cycleSubCategory(ec, allRequests);
			}
		}
		// 循环，同步所有分类到资源
		if (allRequests != null && allRequests.size() > 0) {
			for (EventCategory ec : allRequests) {
				Operation operation = operationDAO.findUniqueBy("resCode",
						"Request_Category_" + ec.getEventId());
				if (operation == null) {
					addCategoryOperation(ec);
				}// 同步资源
			}
		}

	}

	/**
	 * Check all nodes
	 * 
	 * @param categoryName
	 * @return List<CategoryTreeViewDTO>
	 */
	@Transactional(readOnly=true)
	public List<CategoryTreeViewDTO> findEventCategorys(String categoryName,
			String flag, Long parentEventId, Long maxViewLevel,int num,int start) {
		boolean isSub = false;
		// Entity collection objects and collection of DTO objects
		List<CategoryTreeViewDTO> listDTOs = new ArrayList<CategoryTreeViewDTO>();
		List<EventCategory> listEntity = new ArrayList<EventCategory>();
		if (parentEventId != null && parentEventId != 0) {
			listEntity = eventCategoryDAO.findBy("eventId", parentEventId);
			isSub = true;
		} else {
			listEntity = eventCategoryDAO.findTreeViews(categoryName);
		}
		String loginUserName = appctx.getCurrentLoginName();
		String ableCategorysStr = "";
		if(("Knowledge").equals(categoryName)){
			ableCategorysStr = "Knowledge_Category_";
		}else if(("Request").equals(categoryName)){
			ableCategorysStr = "Request_Category_";
		}
		Long[] viewAbleCategorys = userInfoService.findCategoryNosByLoginName(
				loginUserName, ableCategorysStr);// 设置查看权限
		List<Long> viewAbleCategorysList = new ArrayList<Long>();
		if (viewAbleCategorys != null && viewAbleCategorys.length > 0) {
			for (Long l : viewAbleCategorys) {
				viewAbleCategorysList.add(l);
			}
		}
		Boolean isAll = false;
		if (flag != null
				&& flag.equals("dataDic")
				|| (!categoryName.equals("Knowledge") && !categoryName
						.equals("Request"))) {
			isAll = true;
		}

		// Traverse the entity set
		for (EventCategory ec : listEntity) {
			// The DTO object tree
			CategoryTreeViewDTO ctDTO = new CategoryTreeViewDTO();
			// Entities into DTO
			KnowledgeEntity2dto(ec, ctDTO, viewAbleCategorysList, isAll,
					 isSub ,num ,start);
			// Added to the collection DTO
			listDTOs.add(ctDTO);
		}

		return listDTOs;
	}

	/**
	 * 查询常用分类树
	 * @param categoryRoot 父分类ROOT
	 * @param parentEventId 父节点
	 * @param flag
	 * @return CategoryTreeViewDTO
	 */

	@Transactional(readOnly=true)
	public CategoryTreeViewDTO findEventCategoryTree(String categoryRoot,String flag, Long parentEventId, Long maxViewLevel,String pageFlag,int num,int start) {
		boolean isSub = false;
		EventCategory ec = eventCategoryDAO.findEventCategoryTreeByParentEventId(parentEventId);
		if (ec == null) {
			ec = eventCategoryDAO.findEventCategoryTree(categoryRoot);
		} else {
			isSub = true;
		}
		if(ec!=null && !StringUtils.hasText(ec.getPath())){
			this.updateAllCategoryPath();
		}
		String ableCategorysStr = "";
		if(("Knowledge").equals(categoryRoot)){
			ableCategorysStr = "Knowledge_Category_";
		}else if(("Request").equals(categoryRoot)){
			ableCategorysStr = "Request_Category_";
		}
		String loginUserName = "";
		//如果是免登陆则loginUserName为""
		if(!"direct".equals(pageFlag)){
			loginUserName = appctx.getCurrentLoginName();
		}
		Long[] viewAbleCategorys = userInfoService.findCategoryNosByLoginName(
				loginUserName, ableCategorysStr);// 设置查看权限

		List<Long> viewAbleCategorysList = new ArrayList<Long>();

		if (viewAbleCategorys != null && viewAbleCategorys.length > 0) {
			for (Long l : viewAbleCategorys) {
				viewAbleCategorysList.add(l);
			}
		}
		
		Boolean isAll = false;
		if (flag != null && flag.equals("dataDic")
				|| (categoryRoot != null && !categoryRoot.equals("Knowledge") && !categoryRoot.equals("Request"))) {
			isAll = true;
		}

		// The DTO object tree
		CategoryTreeViewDTO ctDTO = new CategoryTreeViewDTO();

		// Entities into DTO
		KnowledgeEntity2dto(ec, ctDTO, viewAbleCategorysList, isAll,
				isSub,num,start);
		for (int i = 0; i < ctDTO.getChildren().size(); i++) {
			if ("open".equals(ctDTO.getChildren().get(i).getState())) {
				ctDTO.getChildren().get(i).setState("closed");
			}
		}
		return ctDTO;
	}

	/**
	 * 查询常用分类树
	 * 
	 * @param categoryName
	 *            //分类名称
	 * @param parentEventId
	 *            父节点
	 * @param flag
	 */
	@Transactional(readOnly=true)
	public List<CategoryTreeViewDTO> findEventCategoryTreeSub(
			String categoryName, String flag, Long parentEventId,
			Long maxViewLevel,String pageFlag,int num,int start) {

		EventCategory ec = eventCategoryDAO.findEventCategoryTreeByParentEventId(parentEventId);
	
		String ableCategorysStr = "";
		if(("Knowledge").equals(categoryName)){
			ableCategorysStr = "Knowledge_Category_";
		}else if(("Request").equals(categoryName)){
			ableCategorysStr = "Request_Category_";
		}
		String loginUserName = "";
		//如果是免登陆则loginUserName为""
		if(!"direct".equals(pageFlag)){
			loginUserName = appctx.getCurrentLoginName();
		}
		Long[] viewAbleCategorys = userInfoService.findCategoryNosByLoginName(
				loginUserName, ableCategorysStr);// 设置查看权限
		List<Long> viewAbleCategorysList = new ArrayList<Long>();
		if (viewAbleCategorys != null && viewAbleCategorys.length > 0) {
			for (Long l : viewAbleCategorys) {
				viewAbleCategorysList.add(l);
			}
		}
		
		Boolean isAll = false;
		if (flag != null&& flag.equals("dataDic")
				|| (!categoryName.equals("Knowledge") && !categoryName.equals("Request"))) {
			isAll = true;
		}

		// The DTO object tree
		List<CategoryTreeViewDTO> categoryTreeViewDTOList = new ArrayList<CategoryTreeViewDTO>();

		// Entities into DTO
		KnowledgeEntity2dtoSub(ec, categoryTreeViewDTOList,viewAbleCategorysList, isAll,num,start);

		return categoryTreeViewDTOList;
	}

	/**
	 * find Category
	 * 
	 * @param eventId
	 */
	@Transactional
	public EventCategoryDTO findEventCategoryById(long eventId) {
		EventCategoryDTO ecDTO = new EventCategoryDTO();
		EventCategory entity = eventCategoryDAO.findById(eventId);
		if (entity != null) {
			EventCategoryDTO.entity2dto(entity, ecDTO);
			if (entity.getParentEvent() != null) {
				EventCategory sonTree = entity.getParentEvent();
				ecDTO.setParentEventId(sonTree.getEventId());
				ecDTO.setParentEventName(sonTree.getEventName());
			}
		}

		return ecDTO;

	}

	/**
	 * Modify node
	 * 
	 * @param ecDTO
	 */
	@Transactional
	public void mergeEventCategory(EventCategoryDTO ecDTO) {
		// Entity object
		EventCategory entity = eventCategoryDAO.findById(ecDTO.getEventId());

		if (ecDTO.getEventName() != null) {
			entity.setEventName(ecDTO.getEventName());
		}

		if (ecDTO.getEventDescription() != null) {
			entity.setEventDescription(ecDTO.getEventDescription());
		}

		// Determine whether the parent node
		if (ecDTO.getParentEventId() != null) {
			// Get the parent node information
			EventCategory sonTree = entity.getParentEvent();

			// Parent association
			entity.setParentEvent(sonTree);
		}

		// Modify the object
		eventCategoryDAO.merge(entity);
		if(entity.getParentEvent()!=null){
			entity.setPath(entity.getParentEvent().getPath()+entity.getEventId()+"/");
			entity.setPathAlias(entity.getParentEvent().getPathAlias()+entity.getEventName()+"/");
		}else{
			entity.setPath(entity.getEventId()+"/");
			entity.setPathAlias(entity.getEventName()+"/");
		}
	}

	/**
	 * According to modify the node state Sesssion
	 * 
	 * @param ec
	 */
	@Transactional
	public void updateEventCategory(EventCategoryDTO ec) {
		// DAO parent class method, based ID for entity
		EventCategory entity = eventCategoryDAO.findById(ec.getEventId());

		entity.setEavId(ec.getEavId());
		entity.setFormId(ec.getFormId());
		// Modify the node ID
		if (ec.getEventId() != null) {
			entity.setEventId(ec.getEventId());
		}

		// scores
		if (ec.getScores() > 0) {
			entity.setScores(ec.getScores());
		}

		// Changes name
		if (ec.getEventName() != null) {
			entity.setEventName(ec.getEventName());
		}
		

		// Changes described
		if (ec.getEventDescription() != null) {
			entity.setEventDescription(ec.getEventDescription());
		}

		// Modify a child node
		if (ec.getParentEventId() != null) {
			EventCategory tv = eventCategoryDAO.findById(ec.getParentEventId());

			entity.setParentEvent(tv);
		}
		// Modify a CategoryCodeRule
		if (ec.getCategoryCodeRule() != null) {
			entity.setCategoryCodeRule(ec.getCategoryCodeRule());
		}
		if(entity.getParentEvent()!=null){
			entity.setPath(entity.getParentEvent().getPath()+entity.getEventId()+"/");
			entity.setPathAlias(entity.getParentEvent().getPathAlias()+entity.getEventName()+"/");
		}else{
			entity.setPath(entity.getEventId()+"/");
			entity.setPathAlias(entity.getEventName()+"/");
		}
		if(!StringUtils.hasText(entity.getCategoryRoot())){
			editCategoryOperation(entity);
		}
		
	}

	/**
	 * Remove the node, including its child nodes
	 * 
	 * @param treeId
	 */
	@Transactional
	public void removeEventCategory(Long treeId) {
		eventCategoryDAO.delete(eventCategoryDAO.findById(treeId));

		deleteCateGoryOperation(treeId);
	}

	/**
	 * Mobile node
	 * 
	 * @param ec
	 */
	@Transactional
	public void changeParent(EventCategoryDTO ec) {
		// Father and son roots for roots
		EventCategory entity = eventCategoryDAO.findById(ec.getEventId());
		EventCategory parent = eventCategoryDAO.findById(ec.getParentEventId());

		// Session state, the associated root
		entity.setParentEvent(parent);
		eventCategoryDAO.merge(entity);
		if(entity.getParentEvent()!=null){
			entity.setPath(entity.getParentEvent().getPath()+entity.getEventId()+"/");
			entity.setPathAlias(entity.getParentEvent().getPathAlias()+entity.getEventName()+"/");
		}else{
			entity.setPath(entity.getEventId()+"/");
			entity.setPathAlias(entity.getEventName()+"/");
		}
	}
	/**
	 * 复制分类信息
	 */
	@Transactional
	public EventCategoryDTO copyCategory(EventCategoryDTO ec) {
		EventCategory parent = eventCategoryDAO.findById(ec.getParentEventId());
		EventCategory entity = eventCategoryDAO.findById(ec.getEventId());
		EventCategory copy = new EventCategory();

		copy.setEventName(entity.getEventName());
		copy.setEventDescription(entity.getEventDescription());
		copy.setParentEvent(parent);

		eventCategoryDAO.save(copy);
		if(copy.getParentEvent()!=null){
			copy.setPath(copy.getParentEvent().getPath()+copy.getEventId()+"/");
		}else{
			copy.setPath(copy.getEventId()+"/");
		}

		setChildren(copy, entity);

		// add mars
		EventCategoryDTO dto = new EventCategoryDTO();
		EventCategoryDTO.entity2dto(copy, dto);
		addCategoryOperation(copy);
		return dto;
	}

	/**
	 * 循环复制子节
	 * 
	 * @param parent
	 * @param children
	 */
	@Transactional
	private void setChildren(EventCategory parent, EventCategory children) {
		if (children.getParentChildren() != null
				&& children.getParentChildren().size() > 0) {
			for (EventCategory ec : children.getParentChildren()) {
				EventCategory newChildren = new EventCategory();
				newChildren.setEventName(ec.getEventName());
				newChildren.setEventDescription(ec.getEventDescription());
				newChildren.setParentEvent(parent);
				eventCategoryDAO.save(newChildren);
				if(newChildren.getParentEvent()!=null){
					newChildren.setPath(newChildren.getParentEvent().getPath()+newChildren.getEventId()+"/");
				}else{
					newChildren.setPath(newChildren.getEventId()+"/");
				}
				addCategoryOperation(newChildren);
				setChildren(newChildren, ec);
			}
		}

	}

	/**
	 * 获取常用分类
	 * 
	 * @param categoryName
	 * @return List<EventCategory>
	 */
	@Transactional()
	public List<EventCategory> findEventCategory(String categoryName) {
		List<EventCategory> eventCategoryList = new ArrayList<EventCategory>();
		List<EventCategory> eventCategory = eventCategoryDAO
				.findTreeViews(categoryName);
		for (EventCategory ec : eventCategory) {
			cycleSubCategory(ec, eventCategoryList);
		}
		return eventCategoryList;
	}

	/**
	 * 递归读取子分类
	 * 
	 * @param entity
	 * @param eventCategoryList
	 */

	private void cycleSubCategory(EventCategory entity,
			List<EventCategory> eventCategoryList) {
		if (entity != null && entity.getDataFlag() != 99) {
			try {
				eventCategoryList.add(entity);
				if (!entity.getParentChildren().isEmpty()) {
					for (EventCategory ecy : entity.getParentChildren()) {
						cycleSubCategory(ecy, eventCategoryList);
					}
				}
			} catch (Exception ex) {
				throw new ApplicationException(
						"Exception caused while converting Entity into DTO: "
								+ ex.getMessage(), ex);
			}

		}
	}

	/**
	 * 导出数据方法
	 * 
	 * @throws Exception
	 */
	@Transactional
	public InputStream exportEventCategory(String categoryName) {
		StringWriter sw = new StringWriter();
		CSVWriter csvw = new CSVWriter(sw);
		LanguageContent lc = LanguageContent.getInstance();
		List<String[]> data = new ArrayList<String[]>();
		if ("Service".equals(categoryName)) {
			data.add(new String[] { lc.getContent("common.id"),
					lc.getContent("label.service.serviceName"),
					lc.getContent("label.service.scores"),
					lc.getContent("common.code"),
					lc.getContent("label.user.description") });
		}/*else if("Knowledge".equals(categoryName)){
			data.add(new String[] { lc.getContent("common.id"),
					lc.getContent("label.categoryName"),
					lc.getContent("label.categoryDescription") });
		}*/else {
			data.add(new String[] { lc.getContent("common.id"),
					lc.getContent("label.categoryName"),
					lc.getContent("label.categoryCode"),
					lc.getContent("label.categoryDescription") });
		}

		List<EventCategory> listEntity = findEventCategory(categoryName);

		if (listEntity != null && listEntity.size() > 0) {

			for (EventCategory item : listEntity) {
				if ("Service".equals(categoryName)) {
					data.add(new String[] { item.getEventId().toString(),
							item.getEventName(), item.getScores() + "",
							item.getCategoryCodeRule(),
							item.getEventDescription() });
				} else {
					data.add(new String[] { item.getEventId().toString(),
							item.getEventName(), item.getCategoryCodeRule(),
							item.getEventDescription() });
				}
			}
		}
		csvw.writeAll(data);
		byte[] bs = null;
		try {
			bs = sw.getBuffer().toString().getBytes("GBK");
		} catch (UnsupportedEncodingException e1) {
			LOGGER.error(e1);
		}
		ByteArrayInputStream stream = null;
		if(bs!=null){
			stream = new ByteArrayInputStream(bs);
		}
		try {
        	if(csvw!=null){
        		csvw.flush();
    			csvw.close();
        	}
			if(sw!=null){
				sw.flush();
				sw.close();
			}
		} catch (IOException e) {
			LOGGER.error(e);
		}
		return stream;
	}

	/**
	 * 导入数据方法.
	 * 
	 * @param importFile
	 * @return String
	 */
	@Transactional
	public String importEventCategory(File importFile) {

		int insert = 0;
		int update = 0;
		int total = 0;
		int failure = 0;
		Reader rd =null;
		CSVReader reader = null;
		try {
			String fileEncode = FileEncodeUtils.getFileEncode(importFile);
			rd = new InputStreamReader(new FileInputStream(importFile),fileEncode);// 以字节流方式读取数据
			reader = new CSVReader(rd);
			String[] line = null;
			try {
				while ((line = reader.readNext()) != null) {

					EventCategory eventCategory = new EventCategory();
					//分类名称
					eventCategory.setEventName(line[1].toString());
					//描述
					eventCategory.setDescription(line[2].toString());
					//父节点
					if (StringUtils.hasText(line[3])) {
						eventCategory.setParentEvent(
								eventCategoryDAO.findBy(
								"categoryRoot", line[3].toString()).get(0));
					}
					eventCategory.setScores(0);
					eventCategory.setCategoryRoot(line[4].toString());
					eventCategoryDAO.save(eventCategory);
					if(eventCategory.getParentEvent()!=null){
						eventCategory.setPath(eventCategory.getParentEvent().getPath()+eventCategory.getEventId()+"/");
					}else{
						eventCategory.setPath(eventCategory.getEventId()+"/");
					
						DataDictionaryGroup entity = new DataDictionaryGroup();
						entity.setGroupName(line[1].toString());
							entity.setGroupCode(line[4].toString());
						entity.setTreeNo(eventCategory.getEventId());
						entity.setGroupType("tree");
						entity.setDataFlag((byte) 1);
						dataDictionaryGroupDAO.save(entity);
					}
					insert++;
					total++;
				}
				return "Total:" + total + ",&nbsp;Insert:" + insert
						+ ",&nbsp;Update:" + update + ",&nbsp;Failure:"
						+ failure;

			} catch (Exception e) {
				throw new ApplicationException("ERROR_CSV_FILE_NOT_EXISTS\n"
						+ e, e);
			}
		} catch (Exception ex) {
			throw new ApplicationException("ERROR_CSV_FILE_IO\n" + ex, ex);
		}finally {
			try {
				if(rd!=null){
					rd.close();
				}
				if(reader!=null){
					reader.close();
				}
			} catch (IOException e) {
				LOGGER.error(e);
			}
		}
	}
	/**
	 * 实体转DTO
	 * @param entity
	 * @param dto
	 */
	private void knowledgeEntity2dto(EventCategory entity,
			CategoryTreeViewDTO dto) {

		try {
			// 如果当前节点是父节点或当前节点的父节点是根节点，那么状态默认Open
			if (entity.getParentChildren().size() > 0) {
				dto.setState("closed");
			}
			if (StringUtils.hasText(entity.getCategoryRoot())) {// 得到父节点标识
				dto.setState("open");
			}
			if (entity.getParentChildren().size() == 0) {
				dto.setState("");
			}

			if ("Service".equals(entity.getCategoryRoot())) {
				dto.setData(entity.getEventName());
			} else {
				dto.setData(entity.getEventName());
			}
			// Display Name

			// Set the map's key and value, a value of entity class
			dto.getAttr().put("id", "" + entity.getEventId());
			dto.getAttr().put("cname", entity.getEventName());
			dto.getAttr().put("eavId", "" + entity.getEavId());
			dto.getAttr().put("formId", "" + entity.getFormId());
			dto.getAttr().put("scores", "" + entity.getScores());
			dto.getAttr().put("description", entity.getEventDescription());
			dto.getAttr().put("categoryCodeRule", entity.getCategoryCodeRule());
			dto.getAttr().put("categoryRoot", entity.getCategoryRoot());
			dto.getAttr().put("state",dto.getState());
			if (entity.getParentEvent() != null) {
				dto.getAttr().put("eventId",
						entity.getParentEvent().getEventId().toString());
			} else {
				dto.getAttr().put("eventId", "0");
			}
		} catch (Exception ex) {
			throw new ApplicationException(
					"Exception caused while converting Entity into DTO: "
							+ ex.getMessage());
		}
	}

	/**
	 * Entities into DTO
	 * 
	 * @param entity
	 *            当前父分类
	 * @param dto
	 *            返回的DTO
	 * @param viewAbleIds
	 *            允许显示的值
	 * @param isAll
	 *            是否显示全部
	 * @param categoryName
	 *            分类名称
	 * @param maxViewLevel
	 *            最大显示层数(默认显示2层)
	 */
	private void KnowledgeEntity2dto(EventCategory entity,
			CategoryTreeViewDTO dto, List<Long> viewAbleIds, Boolean isAll,
			boolean isSub ,int num,int start) {
		if (entity != null && entity.getDataFlag() != 99) {

			try {
				if (isSub) {
					// 得到子节点
					List<EventCategory> eventCategoryList = entity
							.getParentChildren();
					// Determine whether the collection is empty
					if (!eventCategoryList.isEmpty()) {
						// Off
						// Traverse the node set
						for (EventCategory ecy : eventCategoryList) {
							if (ecy != null&& (viewAbleIds.contains(ecy.getEventId()) || isAll)) {
								knowledgeEntity2dto(ecy, dto);
							}
						}
					}
				} else {
					knowledgeEntity2dto(entity, dto);
				}

				syncKnowledgeCategoryOperation(entity);// 同步资源呢

				if (!isSub) {
					// 得到子节点
					List<EventCategory> eventCategoryList = entity
							.getParentChildren();
					// Determine whether the collection is empty
					if (!eventCategoryList.isEmpty()) {
						// Traverse the node set
						if(num>0){
							Boolean bool=true;
							int end =(start+1)*num;
							if(end > eventCategoryList.size()){
								end=eventCategoryList.size();
								bool=false;
							}
							for (int i = start*num; i < end; i++) {
								EventCategory ecy=eventCategoryList.get(i);
								if (ecy != null&& (viewAbleIds.contains(ecy.getEventId()) || isAll)) {
									CategoryTreeViewDTO ctDTO = new CategoryTreeViewDTO();
									knowledgeEntity2dto(ecy, ctDTO);
									ctDTO.getAttr().put("bool", bool+"");
									dto.getChildren().add(ctDTO);
									if(bool && start==0 && i==end-1){
										CategoryTreeViewDTO more = new CategoryTreeViewDTO();
										ecy.setEventName("More...");
										ecy.setEventId(0l);
										more.getAttr().put("start", (start+1)+"");
										ecy.setParentChildren(new ArrayList<EventCategory>());
										knowledgeEntity2dto(ecy, more);
										dto.getChildren().add(more);
									}
								}
							}
						}else{
							for (EventCategory ecy : eventCategoryList) {
								if (ecy != null&& (viewAbleIds.contains(ecy.getEventId()) || isAll)) {
									CategoryTreeViewDTO ctDTO = new CategoryTreeViewDTO();
									knowledgeEntity2dto(ecy, ctDTO);
									dto.getChildren().add(ctDTO);
								}
							}
						}
					}
				}
			} catch (Exception ex) {
				throw new ApplicationException(
						"Exception caused while converting Entity into DTO: "
								+ ex.getMessage());
			}

		}
	}

	/**
	 * Entities into DTO
	 * 
	 * @param entity
	 *            当前父分类
	 * @param categoryTreeViewDTOList
	 * @param viewAbleIds
	 *            允许显示的值
	 * @param isAll
	 *            是否显示全部
	 * @param categoryName
	 *            分类名称
	 * @param maxViewLevel
	 *            最大显示层数(默认显示2层)
	 */
	private void KnowledgeEntity2dtoSub(EventCategory entity,
			List<CategoryTreeViewDTO> categoryTreeViewDTOList,
			List<Long> viewAbleIds, Boolean isAll,int num,int start) {

		if (entity.getDataFlag() != 99) {

			try {
				syncKnowledgeCategoryOperation(entity);// 同步资源呢
				// 得到子节点
				List<EventCategory> eventCategoryList = entity.getParentChildren();
				// Determine whether the collection is empty
				if (!eventCategoryList.isEmpty()) {
					if(num>0){
						Boolean bool=true;
						int end =(start+1)*num;
						if(end >= eventCategoryList.size()){
							end=eventCategoryList.size();
							bool=false;
						}
						for (int i = start*num; i < end; i++) {
							EventCategory ecy=eventCategoryList.get(i);
							if (ecy != null&& (viewAbleIds.contains(ecy.getEventId()) || isAll)) {
								CategoryTreeViewDTO ctDTO = new CategoryTreeViewDTO();
								knowledgeEntity2dto(ecy, ctDTO);
								ctDTO.getAttr().put("bool", bool+"");
								categoryTreeViewDTOList.add(ctDTO);
								if(bool && start==0 && i==end-1){
									CategoryTreeViewDTO more = new CategoryTreeViewDTO();
									ecy.setEventName("More...");
									ecy.setEventId(0l);
									more.getAttr().put("start", (start+1)+"");
									ecy.setParentChildren(new ArrayList<EventCategory>());
									knowledgeEntity2dto(ecy, more);
									categoryTreeViewDTOList.add(more);
								}
							}
						}
					}else{
						for (EventCategory ecy : eventCategoryList) {
	
							if (ecy != null&& (viewAbleIds.contains(ecy.getEventId()) || isAll)) {
								CategoryTreeViewDTO ctDTO = new CategoryTreeViewDTO();
								knowledgeEntity2dto(ecy, ctDTO);
								categoryTreeViewDTOList.add(ctDTO);
								
							}
						}
					}
				}

			} catch (Exception ex) {
				throw new ApplicationException(
						"Exception caused while converting Entity into DTO: "
								+ ex.getMessage());
			}

		}
	}

	/**
	 * 递归查找子分类.
	 * 
	 * @param eventId
	 * @return  List<EventCategoryDTO>
	 */
	@Transactional
	public List<EventCategoryDTO> findSubCategorys(Long eventId) {
		List<EventCategoryDTO> dtos = null;
		EventCategory entity = eventCategoryDAO.findById(eventId);
		// 递归
		List<EventCategory> eventCategoryList = new ArrayList<EventCategory>();
		cycleSubCategory(entity, eventCategoryList);
		if (eventCategoryList != null && eventCategoryList.size() > 0) {
			dtos = new ArrayList<EventCategoryDTO>(eventCategoryList.size());
			for (EventCategory ct : eventCategoryList) {
				EventCategoryDTO dto = new EventCategoryDTO();
				EventCategoryDTO.entity2dto(ct, dto);
				dtos.add(dto);
			}
		}
		return dtos;
	}
	 /**
     * 根据权限递归查找子分类.
     */
	@Transactional
	public List<EventCategoryDTO> findSubCategorysByResType(Long eventId,String resType) {
		List<EventCategoryDTO> dtos = null;
		EventCategory entity = eventCategoryDAO.findById(eventId);
		List<Long> cts = new ArrayList<Long>();
		if("Request".equals(resType)){
			Long[] categorys = userInfoService.findCategoryNosByLoginName(appctx.getCurrentLoginName(), "Request_Category_");// 设置查看权限
			cts =Arrays.asList(categorys);
		}
		// 递归
		List<EventCategory> eventCategoryList = new ArrayList<EventCategory>();
		cycleSubCategory(entity, eventCategoryList);
		if (eventCategoryList != null && eventCategoryList.size() > 0) {
			dtos = new ArrayList<EventCategoryDTO>(eventCategoryList.size());
			for (EventCategory ct : eventCategoryList) {
				if(cts.contains(ct.getEventId())){
					EventCategoryDTO dto = new EventCategoryDTO();
					EventCategoryDTO.entity2dto(ct, dto);
					dtos.add(dto);
				}
			}
		}
		return dtos;
	}
	

	@SuppressWarnings("unchecked")
	public PageDTO findByServiceNos(EventCategoryDTO ec) {
		PageDTO p = eventCategoryDAO.findPagerByIds(ec);
		List<EventCategory> lis = (List<EventCategory>) p.getData();
		List<EventCategoryDTO> dtos = new ArrayList<EventCategoryDTO>();
		for (EventCategory ev : lis) {
			EventCategoryDTO dto = new EventCategoryDTO();
			EventCategoryDTO.entity2dto(ev, dto);
			dtos.add(dto);
		}
		p.setData(dtos);
		return p;
	}

	/**
	 * 递归查找子分类.数组
	 * 
	 * @param eventId
	 * @return  List<EventCategoryDTO>
	 */
	@Transactional
	public List<EventCategoryDTO> findSubCategoryArray(Long[] eventId) {
		List<EventCategoryDTO> categoryDTOArray = new ArrayList<EventCategoryDTO>();

		for (int k = 0; k < eventId.length; k++) {
			EventCategory entity = eventCategoryDAO.findById(eventId[k]);
			// 递归
			List<EventCategory> eventCategoryList = new ArrayList<EventCategory>();
			cycleSubCategory(entity, eventCategoryList);
			if (eventCategoryList != null && eventCategoryList.size() > 0) {
				for (EventCategory ct : eventCategoryList) {
					EventCategoryDTO dto = new EventCategoryDTO();
					EventCategoryDTO.entity2dto(ct, dto);
					
					StringBuffer str = new StringBuffer();
					str.append(ct.getEventName() + "/");
					str = categoryParentEvent(ct, str);
					String locationName = str.toString().substring(0, str.toString().length() - 1);
					if(locationName.lastIndexOf("/")!=-1){
						locationName = locationName.substring(0, locationName.lastIndexOf("/"));
					}
					String[] arrys = locationName.split("/");
					locationName = "";
					for(int i = arrys.length-1 ; i >= 0 ; i --){
						locationName += arrys[i]+"/";
					}
					dto.setPrentFullName(locationName.substring(0, locationName.length() - 1));
					
					categoryDTOArray.add(dto);
				}
			}
		}
		return categoryDTOArray;
	}
	
	private StringBuffer categoryParentEvent(EventCategory ec, StringBuffer str) {
		if (ec.getParentEvent() != null) {
			EventCategory listCategory = eventCategoryDAO.findById(ec.getParentEvent().getEventId());
			if (listCategory != null && !"Request".equals(listCategory.getCategoryRoot())) {
				str.append(listCategory.getEventName() + "/");
				if (listCategory.getParentEvent() != null) {
					categoryParentEvent(listCategory, str);
				}
			}
		}
		return str;
	}

	/**
	 * 根据分类编号数组查询分类信息
	 */
	public List<EventCategoryDTO> findScheduledCategoryArray(Long[] eventId) {
		List<EventCategoryDTO> categoryDTOArray = new ArrayList<EventCategoryDTO>();
		if(eventId!=null){
			for (int k = 0; k < eventId.length; k++) {
				EventCategory entity = eventCategoryDAO.findById(eventId[k]);
				EventCategoryDTO dto = new EventCategoryDTO();
				EventCategoryDTO.entity2dto(entity, dto);
				categoryDTOArray.add(dto);
			}
		}
		return categoryDTOArray;
	}
	
	/**
	 * 对全部的分类进行Path更新
	 */
	private void updateAllCategoryPath(){
		List<EventCategory> eventCategoryList = eventCategoryDAO.findAll();
		for(EventCategory entity : eventCategoryList){
			if(entity.getParentEvent()!=null){
				entity.setPath(entity.getParentEvent().getPath()+entity.getEventId()+"/");
				entity.setPathAlias(entity.getParentEvent().getPathAlias()+entity.getEventName()+"/");
			}else{
				entity.setPath(entity.getEventId()+"/");
				entity.setPathAlias(entity.getEventName()+"/");
			}
		}
	}
	/**
	 * 根据父节点查询所有子分类id组
	 * @param eventId
	 * @return
	 */
	@Transactional
	public Long[] findSubCategoryIdsByEventId(Long eventId){
		Set<Long> longList = new HashSet<Long>();// 唯一集合
		if (eventId != null) {
			EventCategory eventCategory = eventCategoryDAO.findById(eventId);
			List<EventCategory> listec=findSubCategoryByPath(eventCategory.getPath());
			for(EventCategory ec:listec){
				longList.add(ec.getEventId());
			}
		}
		Long[] toArray = longList.toArray(new Long[longList.size()]);
		return toArray;
	}
	/**
     * 根据Path路径查询子分类
     * @param path 分类路径
     * @return 返回当前路径下的所有分类
     */
	public List<EventCategory> findSubCategoryByPath(String path) {
		List<EventCategory> result=null;
		if(StringUtils.hasText(path))
			result= eventCategoryDAO.findSubCategoryByPath(path);
		return result;
	}
	
	/**
	 * 获取下拉树所需数据
	 * @param categoryRoot
	 * @return
	 */
	public PullDownTreeViewDTO getCategoryCombotreeData(String categoryRoot){
		PullDownTreeViewDTO dto = new PullDownTreeViewDTO();
		EventCategory ec = eventCategoryDAO.findEventCategoryTree(categoryRoot);
		dto.setState("open");
		if(ec!=null){
			if (ec.getParentChildren().size() == 0) {
				dto.setState("");
			}
			dto.setId(ec.getEventId());
			dto.setText(ec.getEventName());
			List<EventCategory> eventCategoryList = ec.getParentChildren();
			// Determine whether the collection is empty
			if (!eventCategoryList.isEmpty()) {
				// Off
				// Traverse the node set
				for (EventCategory entity : eventCategoryList) {
					if (entity != null) {
						PullDownTreeViewDTO pdto = new PullDownTreeViewDTO();
						// 如果当前节点是父节点或当前节点的父节点是根节点，那么状态默认Open
						if (entity.getParentChildren().size() > 0) {
							pdto.setState("closed");
						}
						pdto.setId(entity.getEventId());
						pdto.setText(entity.getEventName());
						dto.getChildren().add(pdto);
					}
				}
			}
		}
		
		return dto;
	}

	@Transactional
	public EventCategoryDTO findLocationNameById(Long eventId) {
		EventCategoryDTO dto = new EventCategoryDTO();
			EventCategory ec = eventCategoryDAO.findById(eventId);
			if (ec != null) {
				dto.setEventId((ec.getEventId()));
				if(ec.getParentEvent()==null){
					dto.setCategoryLocation(ec.getEventName());
				}else{
					StringBuffer str = new StringBuffer();
					str.append(ec.getEventName() + "/");
					str = categoryParentEvent(ec, str);
					String locationName = str.toString().substring(0, str.toString().length() - 1);
					locationName = locationName.substring(0, locationName.lastIndexOf("/"));
					String[] arrys = locationName.split("/");
					locationName = "";
					for(int i = arrys.length-1 ; i >= 0 ; i --){
						locationName += arrys[i]+"/";
					}
					dto.setCategoryLocation(locationName.substring(0, locationName.length() - 1));
				}
			}
			return dto;
	}
	
	
}
